/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.war.metier;

import com.ejb.metier.IOrderManager;
import com.ejb.persistence.Invoice;
import com.ejb.persistence.Order;
import com.ejb.persistence.OrderState;
import com.war.helpers.HelperMessageHtml;
import com.war.session.CartSession;
import com.war.session.UserSession;
import com.war.webservice.CheckCreditCard;
import com.war.webservice.CreditCard;
import com.war.webservice.CreditCard_Service;
import com.war.webservice.ObjectFactory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.ejb.EJB;
import javax.el.ELContext;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.ValueChangeEvent;

/**
 *
 * @author Ambroise
 * Class used to manage orders
 */
@ManagedBean(name="orderManager")
@RequestScoped
public class OrderManager {

    @EJB
    private IOrderManager orderManagerBean;
    private List<Order> orders;
    private String creditCard;
    private ELContext elContext = FacesContext.getCurrentInstance().getELContext();
    //private HashMap<Order, OrderState> state;
    private OrderState[] states;
    private String state;
	
	/**
	 * Import the UserSession.
	 */
	private UserSession session = (UserSession) FacesContext.getCurrentInstance().getApplication().getELResolver().getValue(elContext, null, "userSession");
    private CartSession cart = (CartSession) FacesContext.getCurrentInstance().getApplication().getELResolver().getValue(elContext, null, "cartSession");
    
    /**
     * Creates a new instance of OrderManager
     */
    public OrderManager() {
    }
    
    public String createOrder(){
        String retour = "resumeOrders?faces-redirect=true";
        
        if (!session.getIsLogged()){
            retour = "connection?faces-redirect=true";
            HashMap<String, Object> m = new HashMap<String, Object>();
            m.put("type", "info");
            m.put("message", "Vous devez être connecté pour passer une commande.");
            ArrayList<HashMap<String, Object>> messages = session.getMessages();
            messages.add(m);
            session.setMessages(messages); 
        }
        
        return retour;
    }
    
    public String validateOrder(){
        OrderManager order = (OrderManager) FacesContext.getCurrentInstance().getApplication().getELResolver().getValue(elContext, null, "orderManager");

        // Boolean for check if the order is valid and accepted.
        boolean success = false;
        String retour = "";// If used, refresh the page.
        creditCard = creditCard.trim().replaceAll(" ", "");
        if (this.verifyCardNumber(creditCard)){
            HashMap<Long, Integer> invoices = new HashMap<Long, Integer>();
            for (Invoice in:cart.getInvoices()){
                invoices.put(in.getBook().getId(), in.getQuantity());
            }
            success = orderManagerBean.addOrder(session.getUserId(), invoices);
            cart.setInvoices(null);
            if (success){
                HashMap<String, Object> m = new HashMap<String, Object>();
                m.put("type", "success");
                m.put("message", "Votre commande a été validée.");
                ArrayList<HashMap<String, Object>> messages = session.getMessages();
                messages.add(m);
                session.setMessages(messages);
            }else {
                HashMap<String, Object> m = new HashMap<String, Object>();
                m.put("type", "error");
                m.put("message", "Une erreur s'est produite durant la validation de votre commande.");
                ArrayList<HashMap<String, Object>> messages = session.getMessages();
                messages.add(m);
                session.setMessages(messages);
            }
        } else {
            HashMap<String, Object> m = new HashMap<String, Object>();
            m.put("type", "error");
            m.put("message", "Le numéro de carte de crédit est invalide.");
            ArrayList<HashMap<String, Object>> messages = session.getMessages();
            messages.add(m);
            session.setMessages(messages);
        }
        
        return (success)? order.setWaitingOrders() : retour;
    }
    
    /**
     * Use web service for check credit card number.
     * @param cardNumber
     * @return boolean
     */
    private boolean verifyCardNumber(String cardNumber){
        CreditCard creditCardWebService = new CreditCard_Service().getCreditCardPort();
        return creditCardWebService.checkCreditCard(cardNumber);
    }
    
    public Float getTotalPrice(Order order){
        Float total = 0f;
        
        for (Invoice in:order.getInvoices()){
            total += in.getQuantity() * in.getBook().getPrice();
        }
        
        return total;
    }
    
    public String updateOrderState(Long orderId){
        Boolean b = orderManagerBean.setState(orderId, OrderState.valueOf(this.state));
        return "administrationOrders?faces-rediret=true";
    }

    public List<Order> getOrders() {
        return orders;
    }

    public String setAllOrders() {
        this.orders = orderManagerBean.getOrders(session.getUserId(), false);
        return "historyOrders?face-redirect=true";
    }
    
    public String setWaitingOrders() {
        this.orders = orderManagerBean.getOrdersByUserAndTwoStates(session.getUserId(), OrderState.Préparation, OrderState.Validée);
        return "waitingOrders?face-redirect=true";
    }
    
    public List<Order> setAllOrdersAdmin() {
        return orderManagerBean.getOrders(Long.MIN_VALUE, true);
    }
    
    public String setShippedOrders() {
        this.orders = orderManagerBean.getOrdersByUserAndStates(session.getUserId(), OrderState.Envoyée);
        return "shippedOrders?face-redirect=true";
    }

    public void change(ValueChangeEvent ae){
        this.state = ae.getNewValue().toString();
    }

    public OrderState[] getStates() {
        return OrderState.values();
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }


    public String getCreditCard() {
        return creditCard;
    }

    public void setCreditCard(String creditCard) {
        this.creditCard = creditCard;
    }
}
